package com.macro.mall.portal.component;

import cn.hutool.core.collection.CollectionUtil;
import com.macro.mall.common.exception.Asserts;
import com.macro.mall.common.util.DateUtil;
import com.macro.mall.mapper.*;
import com.macro.mall.model.*;
//import com.macro.mall.portal.service.OmsPortalOrderService;
import com.macro.mall.portal.dao.PortalOrderDao;
import com.macro.mall.portal.dao.PortalOrderItemDao;
import com.macro.mall.portal.domain.OmsOrderDetail;
import com.macro.mall.portal.domain.QueueEnum;
import com.macro.mall.portal.service.OmsPortalOrderService;
import com.macro.mall.wx.service.GetAccessTokenService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 订单超时取消并解锁库存的定时器
 */
@Component
public class OrderTimeOutCancelTask {
    private Logger LOGGER = LoggerFactory.getLogger(OrderTimeOutCancelTask.class);
    @Autowired
    private OmsPortalOrderService portalOrderService;
    @Autowired
    private OmsDistributionOrderMapper omsDistributionOrderMapper;
    @Autowired
    private OmsDistributionStoreOrderMapper distributionStoreOrderMapper;
    @Autowired
    private UmsStoreMapper umsStoreMapper;
    @Autowired
    private OmsOrderSettingMapper orderSettingMapper;
    @Autowired
    private OmsOrderSettingMapper omsOrderSettingMapper;
    @Autowired
    private OmsOrderMapper omsOrderMapper;
    @Autowired
    private OmsOrderItemMapper omsOrderItemMapper;
    @Autowired
    private PortalOrderDao portalOrderDao;
    @Autowired
    private PortalOrderItemDao orderItemDao;
    @Autowired
    private GetAccessTokenService tokenService;
    @Autowired
    private MessageSender messageSender;

    /**
     * cron表达式：Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
     * 每10分钟扫描一次，扫描设定超时时间之前下的订单，如果没支付则取消该订单
     */
    @Scheduled(cron = "0 0/10 * ? * ?")
    private void cancelTimeOutOrder() {
        Integer count = portalOrderService.cancelTimeOutOrder();
        LOGGER.info("取消订单，并根据sku编号释放锁定库存，取消订单数量：{}", count);
    }

    /**
     * cron表达式：Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
     * 0点，6点，12点，18点执行一次
     */
    @Scheduled(cron = "0 0 0,6,12,18 * * ?")
//    @Scheduled(cron = "0 0/10 * ? * ?")
    private void settlementDistribution() {
        System.out.println("所有待结算的分销订单");
        UmsStoreExample storeExample = new UmsStoreExample();
        //开启状态
        storeExample.createCriteria().andStatusEqualTo(1);
        List<UmsStore> umsStores = this.umsStoreMapper.selectByExample(storeExample);
        OmsDistributionOrderExample example = new OmsDistributionOrderExample();
        example.createCriteria().andStatusEqualTo(OmsDistributionOrder.STATUS.FINISH.value());
        Calendar calendar = Calendar.getInstance();
        //所有待结算的分销订单
        List<OmsDistributionOrder> omsDistributionOrders = this.omsDistributionOrderMapper.selectByExample(example);
        Map<Long, List<OmsDistributionOrder>> collect = omsDistributionOrders.stream().collect(Collectors.groupingBy(distribution -> distribution.getStoreId()));
        for (UmsStore store : umsStores) {
            store.getSettlementCommissionTime();
            calendar.setTime(new Date());
            calendar.set(Calendar.SECOND, -store.getSettlementCommissionTime() * 24 * 60 * 60);
            Date time = calendar.getTime();
            List<OmsDistributionOrder> list = collect.get(store.getId());
            //获取需要结算的佣金订单
            if (CollectionUtil.isNotEmpty(list)) {
                List<OmsDistributionOrder> omsDistributionOrderList = list.stream().filter(e -> e.getCreateTime().before(time)).collect(Collectors.toList());
                for (OmsDistributionOrder omsDistributionOrder : omsDistributionOrderList) {
                    omsDistributionOrder.setStatus(OmsDistributionOrder.STATUS.SETTLEMENT.value());
                    omsDistributionOrder.setUpdateTime(new Date());
                    this.omsDistributionOrderMapper.updateByPrimaryKeySelective(omsDistributionOrder);
                }
            }
        }
    }

    /**
     * cron表达式：Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
     * 0点10分，6点10分，12点10分，18点10分执行一次
     */
    @Scheduled(cron = "0 10 0,6,12,18 * * ?")
//    @Scheduled(cron = "0 0/10 * ? * ?")
    private void settlementStoreDistribution() {
        OmsOrderSettingExample settingExample = new OmsOrderSettingExample();
        OmsOrderSetting omsOrderSetting = orderSettingMapper.selectByExample(settingExample).get(0);
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.SECOND, -omsOrderSetting.getWithdrawalTime() * 24 * 60 * 60);
        OmsDistributionStoreOrderExample example = new OmsDistributionStoreOrderExample();
        example.createCriteria()
                .andStatusEqualTo(3)
                .andCreateTimeLessThanOrEqualTo(calendar.getTime());
        //所有待结算的分销订单
        List<OmsDistributionStoreOrder> omsDistributionOrders = this.distributionStoreOrderMapper.selectByExample(example);
        //获取需要结算的佣金订单
        if (CollectionUtil.isNotEmpty(omsDistributionOrders)) {
            for (OmsDistributionStoreOrder omsDistributionOrder : omsDistributionOrders) {
                omsDistributionOrder.setStatus(6);
                omsDistributionOrder.setUpdateTime(new Date());
                this.distributionStoreOrderMapper.updateByPrimaryKeySelective(omsDistributionOrder);
            }
        }
    }

    /**
     * 确认收货定时器
     * 订单发货后多少天后确认收货
     * @author 孙晓亮
     * date 2020年9月18日
     * cron表达式：Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
     * 0点，6点，12点，18点执行一次
     */
    @Scheduled(cron = "0 0 0,6,12,18 * * ?")
//    @Scheduled(cron = "0 0/10 * ? * ?")
    public void changeOrderStatus() {
        //取出订单设置表中多少天后确认收货
        OmsOrderSettingExample omsOrderSettingExample = new OmsOrderSettingExample();
        List<OmsOrderSetting> omsOrderSettingList = omsOrderSettingMapper.selectByExample(omsOrderSettingExample);
        Integer confirmOvertime = omsOrderSettingList.get(0).getConfirmOvertime();
        //修改订单表中日期距离当前时间大于确认收货天数的订单状态为已收货
        //取得开始时间(设置的天数)和当前时间作为结束时间
        Date endDate = new Date();
        Date startDate = DateUtil.getDay(endDate, -confirmOvertime);
        OmsOrderExample omsOrderExample = new OmsOrderExample();
        OmsOrderExample.Criteria criteria = omsOrderExample.createCriteria();
        //查询出状态为已发货，发货日期小于当前日期，发货日期不在开始时间和结束时间之间的订单并修改状态
        criteria.andStatusEqualTo(2);
        criteria.andDeliveryTimeNotBetween(startDate, endDate);
        criteria.andDeliveryTimeLessThan(endDate);
        List<OmsOrder> omsOrderList = omsOrderMapper.selectByExample(omsOrderExample);
        omsOrderList.forEach(p -> {
            OmsOrderDetail detail = this.portalOrderDao.getDetail(p.getId());
            List<OmsOrderItem> collect = detail.getOrderItemList().stream().filter(omsOrderItem -> OmsOrderItem.STATUS.WAIT_RECEIVE.value() == omsOrderItem.getStatus()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)) {
                p.setStatus(3);
                p.setModifyTime(endDate);
                p.setConfirmStatus(1);
                p.setReceiveTime(endDate);
                omsOrderMapper.updateByPrimaryKey(p);
                this.orderItemDao.updateOrderItemStatus(collect, OmsOrderItem.STATUS.FINISH.value());
                if(!p.getOrderType().equals(4)){
                    this.messageSender.sendMessage(p.getId(), 0, QueueEnum.QUEUE_DISTRIBUTION_CREAT);
                }
            }
        });

    }

    /**
     * 更换小程序token
     * author zhouboyu
     * date 2020年9月20日
     * cron表达式：Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
     * 每小时执行一次
     */
    @Scheduled(cron = "0 0/30 * * * ? ")
//    @Scheduled(cron = "0 0 0/1 * * ?  ")
    public void getAccessToken() {
        LOGGER.info("更换小程序token--------------------");
        OmsOrderSetting omsOrderSetting = new OmsOrderSetting();
        omsOrderSetting.setId(1L);
        omsOrderSetting.setAccessToken(this.tokenService.getAccessToken());
        this.omsOrderSettingMapper.updateByPrimaryKeySelective(omsOrderSetting);
    }

}
